﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace team1337blarg
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class PaulsGame : GameScreen
    {
        //GraphicsDeviceManager graphics;
        ContentManager content;
        SpriteBatch spriteBatch;
        Texture2D myTexture;
        Texture2D myArrow;
        Texture2D background;
        SoundEffect arrowFired;
        Song backgroundSong;
        int maxScreenHeight = 480;
        int maxScreenWidth = 853;
        LinkedList<ArrowSprite> myArrows = new LinkedList<ArrowSprite>(); //list of arrows that are flying through the air
        MySprite mainCharacterSprite = new MySprite();//main character
        ArrowSprite theLoadedArrow = new ArrowSprite();//the arrow sitting in the bow
        KeyboardState oldKeyboardState;
        bool arrowLoaded = false;
        int buttonPressed = 0;//stores which direction you are firing the arrow

        public PaulsGame()
        {
            mainCharacterSprite.spriteStartX = 3;
            mainCharacterSprite.spriteStartY = 0;
            mainCharacterSprite.spriteWidth = 34;
            mainCharacterSprite.spriteHeight = 38;
            mainCharacterSprite.screenPositionX = (maxScreenWidth / 2) - mainCharacterSprite.spriteWidth;
            mainCharacterSprite.screenPositionY = (maxScreenHeight / 2) - mainCharacterSprite.spriteHeight;
            mainCharacterSprite.moveSpeed = 10;
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        public override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            oldKeyboardState = Keyboard.GetState();
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");
            spriteBatch = ScreenManager.SpriteBatch;
            myTexture = content.Load<Texture2D>(@"Paul/Textures/knight");
            myArrow = content.Load<Texture2D>(@"Paul/Textures/arrow");
            arrowFired = content.Load<SoundEffect>(@"Paul/Sounds/arrow swoosh");
            background = content.Load<Texture2D>(@"Paul/Textures/background");
            backgroundSong = content.Load<Song>(@"Paul/Music/background song");
            //MediaPlayer.Play(backgroundSong);

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        public override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);
            // TODO: Add your update logic here


            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                
            }
            if (Keyboard.GetState().IsKeyDown(Keys.A))
            {
                mainCharacterSprite.screenPositionX -= mainCharacterSprite.moveSpeed;
                if (!theLoadedArrow.isAway)
                {
                    theLoadedArrow.screenPositionX -= mainCharacterSprite.moveSpeed;
                }
            }
            if (Keyboard.GetState().IsKeyDown(Keys.S))
            {
                mainCharacterSprite.screenPositionY += mainCharacterSprite.moveSpeed;
                if (!theLoadedArrow.isAway)
                {
                    theLoadedArrow.screenPositionY += mainCharacterSprite.moveSpeed;
                }
            }
            if (Keyboard.GetState().IsKeyDown(Keys.W))
            {
                mainCharacterSprite.screenPositionY -= mainCharacterSprite.moveSpeed;
                if (!theLoadedArrow.isAway)
                {
                    theLoadedArrow.screenPositionY -= mainCharacterSprite.moveSpeed;
                }
            }
            if (Keyboard.GetState().IsKeyDown(Keys.D))
            {
                mainCharacterSprite.screenPositionX += mainCharacterSprite.moveSpeed;
                if (!theLoadedArrow.isAway)
                {
                    theLoadedArrow.screenPositionX += mainCharacterSprite.moveSpeed;
                }
            }
            mainCharacterSprite.CheckIfOnScreen(maxScreenWidth, maxScreenHeight);

            if (Keyboard.GetState().IsKeyDown(Keys.NumPad1) || Keyboard.GetState().IsKeyDown(Keys.End) ||
                Keyboard.GetState().IsKeyDown(Keys.NumPad2) || Keyboard.GetState().IsKeyDown(Keys.Down) ||
                Keyboard.GetState().IsKeyDown(Keys.NumPad3) || Keyboard.GetState().IsKeyDown(Keys.PageDown) ||
                Keyboard.GetState().IsKeyDown(Keys.NumPad4) || Keyboard.GetState().IsKeyDown(Keys.Left) ||
                Keyboard.GetState().IsKeyDown(Keys.NumPad6) || Keyboard.GetState().IsKeyDown(Keys.Right) ||
                Keyboard.GetState().IsKeyDown(Keys.NumPad7) || Keyboard.GetState().IsKeyDown(Keys.Home) ||
                Keyboard.GetState().IsKeyDown(Keys.NumPad8) || Keyboard.GetState().IsKeyDown(Keys.Up) ||
                Keyboard.GetState().IsKeyDown(Keys.NumPad9) || Keyboard.GetState().IsKeyDown(Keys.PageUp))
            {
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad1) || Keyboard.GetState().IsKeyDown(Keys.End))
                {
                    buttonPressed = 1;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad2) || Keyboard.GetState().IsKeyDown(Keys.Down))
                {
                    buttonPressed = 2;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad3) || Keyboard.GetState().IsKeyDown(Keys.PageDown))
                {
                    buttonPressed = 3;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad4) || Keyboard.GetState().IsKeyDown(Keys.Left))
                {
                    buttonPressed = 4;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad6) || Keyboard.GetState().IsKeyDown(Keys.Right))
                {
                    buttonPressed = 6;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad7) || Keyboard.GetState().IsKeyDown(Keys.Home))
                {
                    buttonPressed = 7;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad8) || Keyboard.GetState().IsKeyDown(Keys.Up))
                {
                    buttonPressed = 8;
                }
                if (Keyboard.GetState().IsKeyDown(Keys.NumPad9) || Keyboard.GetState().IsKeyDown(Keys.PageUp))
                {
                    buttonPressed = 9;
                }

                if (!arrowLoaded)
                {
                    ArrowSprite myFirstArrow = new ArrowSprite();
                    myFirstArrow.StandardArrow(buttonPressed);
                    myFirstArrow.CheckIfOnScreen(maxScreenWidth, maxScreenHeight, mainCharacterSprite);

                    myArrows.AddLast(myFirstArrow);
                    theLoadedArrow = myArrows.Last();
                    arrowLoaded = true;
                }
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad1) || Keyboard.GetState().IsKeyDown(Keys.End))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad1) || oldKeyboardState.IsKeyDown(Keys.End)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad2) || Keyboard.GetState().IsKeyDown(Keys.Down))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad2) || oldKeyboardState.IsKeyDown(Keys.Down)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad3) || Keyboard.GetState().IsKeyDown(Keys.PageDown))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad3) || oldKeyboardState.IsKeyDown(Keys.PageDown)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad4) || Keyboard.GetState().IsKeyDown(Keys.Left))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad4) || oldKeyboardState.IsKeyDown(Keys.Left)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad6) || Keyboard.GetState().IsKeyDown(Keys.Right))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad6) || oldKeyboardState.IsKeyDown(Keys.Right)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad7) || Keyboard.GetState().IsKeyDown(Keys.Home))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad7) || oldKeyboardState.IsKeyDown(Keys.Home)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad8) || Keyboard.GetState().IsKeyDown(Keys.Up))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad8) || oldKeyboardState.IsKeyDown(Keys.Up)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            if (!(Keyboard.GetState().IsKeyDown(Keys.NumPad9) || Keyboard.GetState().IsKeyDown(Keys.PageUp))
                && (oldKeyboardState.IsKeyDown(Keys.NumPad9) || oldKeyboardState.IsKeyDown(Keys.PageUp)))
            {
                arrowFired.Play();
                theLoadedArrow.isAway = true;
                arrowLoaded = false;
            }

            oldKeyboardState = Keyboard.GetState();

            foreach (ArrowSprite theArrow in myArrows)
            {
                if (theArrow.isAway)//arrow has been fired, update direction
                {
                    myArrows.Find(theArrow).Value.updateDirection(mainCharacterSprite);
                }
                if (theArrow.screenPositionX >= maxScreenWidth || theArrow.screenPositionY >= maxScreenHeight ||
                    theArrow.screenPositionX <= 0 || theArrow.screenPositionY <= 0)
                {
                    //myArrows.Remove(theArrow);
                    myArrows.Find(theArrow).Value.deleteThis = true;
                    //currently does not delete the arrow, simply marks it for deletion, on to do list
                }
            }
            if (!theLoadedArrow.isAway)
            {
                theLoadedArrow.CheckIfOnScreen(maxScreenWidth, maxScreenHeight, mainCharacterSprite);
            }
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                              Color.CornflowerBlue, 0, 0);

            // TODO: Add your drawing code here

            spriteBatch.Begin();//background
            spriteBatch.Draw(
            background,
            new Rectangle
                (
                0,
                0,
                maxScreenWidth,
                maxScreenHeight
                ),
            new Rectangle
                (
                0,
                0,
                639,
                479
                ),
            Color.White);
            spriteBatch.End();


            spriteBatch.Begin();//character
            spriteBatch.Draw(
            myTexture,
            new Rectangle
                (
                mainCharacterSprite.screenPositionX,
                mainCharacterSprite.screenPositionY,
                mainCharacterSprite.spriteWidth,
                mainCharacterSprite.spriteHeight
                ),
            new Rectangle
                (
                mainCharacterSprite.spriteStartX,
                mainCharacterSprite.spriteStartY,
                mainCharacterSprite.spriteWidth,
                mainCharacterSprite.spriteHeight
                ),
            Color.White);
            spriteBatch.End();


            spriteBatch.Begin();//arrows
            if (myArrows.Count > 0)
            {

                foreach (ArrowSprite theArrow in myArrows)
                {
                    
                    spriteBatch.Draw(
                    myArrow,
                    new Rectangle
                        (
                        theArrow.screenPositionX,
                        theArrow.screenPositionY,
                        theArrow.arrowWidth,
                        theArrow.arrowHeight
                        ),
                    new Rectangle
                        (
                        theArrow.arrowStartX,
                        theArrow.arrowStartY,
                        theArrow.arrowWidth,
                        theArrow.arrowHeight
                        ),
                    Color.White);
                }
            }
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

/*
 * to do LIST
 * -delete arrows in the arrow linked list
 * -fix the arrows disappearing off the top and bottom of screen while holding movement against the top or bottom of screen
*/